package com.hengxing.demo.Controller;

import com.hengxing.demo.Service.TagService;
import com.hengxing.demo.model.ResponseBean;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 简单数字标签控制
 * @author hengxing
 * @version 1.0
 * @project SocketDemoHx
 * @date 5/30/2023 15:11:06
 */
@RestController
@Tag(name = "简单数字标签控制接口",description = "连接、断连、显示数字、设定闪烁次数和颜色")
public class SimpleController {

    @Autowired
    TagService tagService;

    /**
     * 连接控制器
     *
     * @Param ip
     * @Return java.lang.String
     * @Author hengxing
     * @Date 5/30/2023 18:25:16
     */
    @GetMapping("/con/{ip}")
    @Operation(summary = "与控制器建立连接",
            description = "提供控制器的IP即可连接",
            parameters = {
                @Parameter(name = "ip",description = "控制器IP地址",example = "169.254.56.22")
            },
            responses = {
                @ApiResponse(description = "返回成功信息",
                        responseCode = "200",
                        content = @Content(mediaType = "application/json")
                ),
                @ApiResponse(
                        description = "返回失败信息",
                        responseCode = "500",
                        content = @Content(mediaType = "application/json")
                )
            }
    )
    public ResponseBean connect(@PathVariable("ip") String ip){
        tagService.connect(ip);
        if (tagService.isConnected()){
            return ResponseBean.OK("ip:" + ip + "connect successful! Don't connect again.",null);
        } else return ResponseBean.ERROR("connect failed.Check you ip address and re-connect again.");
    }

    /**
     * 断开连接
     *
     * @Return java.lang.String
     * @Author hengxing
     * @Date 5/31/2023 18:57:50
     */
    @GetMapping("/disconnect")
    @Operation(summary = "与控制器断开连接",
            description = "直接调用即可",
            responses = {
                @ApiResponse(description = "返回成功信息",
                        responseCode = "200",
                        content = @Content(mediaType = "application/json")
                ),
                @ApiResponse(
                        description = "返回失败信息",
                        responseCode = "500",
                        content = @Content(mediaType = "application/json")
                )
            }
    )
    public ResponseBean disconnect(){
        tagService.disconnect();
        if (tagService.isConnected()){
            return ResponseBean.ERROR("DisConnect failed.");
        }else return ResponseBean.OK("DisConnect successful.");
    }

    /**
     * 熄灭标签
     * @Param address 标签地址 1-200 ，252为全部
     * @Return void
     * @Author hengxing
     * @Date 6/1/2023 10:26:09
     */
    @GetMapping("/tagClear/{address}")
    @Operation(summary = "熄灭标签",
            description = "指定要熄灭的标签",
            parameters = {
                @Parameter(name = "address",description = "标签地址,0-200。252为全部标签",example = "252")
            },
            responses = {
                @ApiResponse(description = "返回成功信息",
                        responseCode = "200",
                        content = @Content(mediaType = "application/json")
                ),
                @ApiResponse(
                        description = "地址应在1-200之内，252为全部标签",
                        responseCode = "501",
                        content = @Content(mediaType = "application/json")
                ),
                @ApiResponse(
                        description = "还没有建立连接，请先建立连接",
                        responseCode = "500",
                        content = @Content(mediaType = "application/json")
                )
            }
    )
    public ResponseBean tagClear(@PathVariable("address") int address){
        if (!tagService.isConnected())
            return ResponseBean.ERROR("Not connected yet.Connect first!");
        if (address > 252) {
            HashMap<String, Object> data = new HashMap<>();
            data.put("error message","address should be 1 to 200.252 for all tags.");
            return ResponseBean.ERRORADDRESS("address is not allowed bigger than 252.",data);
        }
        tagService.TagClear((byte) address);
        return ResponseBean.OK("Turn off the light.");
    }

    /**
     * 批量显示数字 TODO 未实际测试
     * @Param data
     * @Return com.hengxing.demo.model.ResponseBean
     * @Author hengxing
     * @Date 6/2/2023 16:04:02
     */
    @PostMapping("tagClear")
    @Operation(summary = "批量熄灭标签",
            description = "传入key为data，value为Integer的list。请注意，同样需要遵守地址小于252的规定，否则可能强转为一个0-255之间的一个值，导致关闭了错误的标签",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "传入的数据",content = {
                    @Content(mediaType = "application/json",
                            examples = {@ExampleObject(name = "成功示例",
                                            value = "{\n" +
                                            "    \"data\": [\n" +
                                            "        1,\n" +
                                            "        2,\n" +
                                            "        3\n" +
                                            "    ]\n" +
                                            "}",
                                            description = "想要熄灭的标签地址。此例中是熄灭地址为1，2，3的三个标签"
                                    )}
                    )
            }),
            responses = {
                @ApiResponse(description = "成功返回信息",
                        responseCode = "200",
                        content = @Content(mediaType = "application/json")
                ),
                @ApiResponse(description = "失败返回信息",
                        responseCode = "502",
                        content = @Content(mediaType = "application/json",
                                examples = @ExampleObject(value = "{\n" +
                                        "    \"status\": 502,\n" +
                                        "    \"message\": \"传入的数据格式有错误,应该为list\",\n" +
                                        "    \"data\": {\n" +
                                        "        \"data\": \"[1,2,3]\"\n" +
                                        "    }\n" +
                                        "}")
                        )
                )
            }
    )
    public ResponseBean tagClearMultiple(@RequestBody Map<String,Object> data){
        Object list = data.get("data");
        if (!(list instanceof List<?>))
            return ResponseBean.ERRORDATA("传入的数据格式有错误,应该为list",data);
        List<Integer> address = (List<Integer>) list;
        for (int a :
                address) {
            tagService.TagClear((byte) a);
        }
        //测试直接返回
        return ResponseBean.OK("请求成功接收",data);
    }


    /**
     * 显示数字，当请求错误时，会返回错误信息和帮助信息
     * @Param address 标签地址 1-200 ，252为全部
	 * @Param number 字符串，可以为浮点数，总长不能超过6字符
     * @Return com.hengxing.demo.model.ResponseBean
     * @Author hengxing
     * @Date 6/1/2023 11:10:03
     */
    @GetMapping("/display/{address}/{number}")
    @Operation(
            summary = "显示数字，当请求错误时，会返回错误信息和帮助信息",
            parameters = {
                    @Parameter(name = "address",description = "标签地址 1-200 ，252为全部",example = "252"),
                    @Parameter(name = "number",description = "要显示的数字",example = "1314")
            },
            responses = {
                    @ApiResponse(
                            description = "还没有建立连接，请先建立连接",
                            responseCode = "500",
                            content = @Content(mediaType = "application/json")
                    ),
                    @ApiResponse(
                            description = "地址应在1-200之内，252为全部标签",
                            responseCode = "501",
                            content = @Content(mediaType = "application/json")
                    ),
                    @ApiResponse(
                            description = "数字不能大于6个字符长度",
                            responseCode = "502",
                            content = @Content(mediaType = "application/json")
                    ),
                    @ApiResponse(
                            description = "返回成功信息",
                            responseCode = "200",
                            content = @Content(mediaType = "application/json")
                    )
            }
    )
    public ResponseBean displayNumber(@PathVariable("address") int address,
                                      @PathVariable() String number
    ){
        if (!tagService.isConnected())
            return ResponseBean.ERROR("Not connected yet.Connect first!");

        if (address > 252) {
            HashMap<String, Object> data = new HashMap<>();
            data.put("error message","address should be 1 to 200.252 for all tags.");
            return ResponseBean.ERRORADDRESS("address is not allowed bigger than 252.",data);
        }
        if (number.length() > 6)
            return ResponseBean.ERRORDATA("Length of number con't longer than 6 character.");

        tagService.displayNumber((byte) address,number);
        return ResponseBean.OK("display successful.");
    }

    /**
     * 批量显示数字 TODO 未实际测试
     * @Param data
     * @Return com.hengxing.demo.model.ResponseBean
     * @Author hengxing
     * @Date 6/2/2023 16:03:14
     */
    @PostMapping("/display")
    @Operation(
            summary = "批量展示数字",
            description = "传入数字字符串和标签地址列表。数字字符串的key为number，标签地址列表key为data",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "以键值对格式传值，标签地址列表是一个list",
                    content = @Content(
                            mediaType = "application/json",
                            examples = {@ExampleObject(value = "{\n" +
                                    "    \"number\":\"1314.2\",\n" +
                                    "    \"data\": [1,2,3]\n" +
                                    "}",
                                    name = "成功示例",
                                    description = "在地址为1，2，3的标签上显示1314.2"
                            ),@ExampleObject(
                                    name = "失败示例",
                                    description = "写错了key值",
                                    value = "{\n" +
                                            "    \"123\":\"1314.2\",\n" +
                                            "    \"data\": [1,2,3]\n" +
                                            "}"
                            )
                            }
                    )
            ),
            responses = {
                    @ApiResponse(description = "成功返回信息",
                            responseCode = "200",
                            content = @Content(mediaType = "application/json"
                            )
                    ),
                    @ApiResponse(description = "失败返回信息",
                            responseCode = "502",
                            content = @Content(mediaType = "application/json")
                    )
            }

    )
    public ResponseBean displayNumberMultiple(@RequestBody Map<String,Object> data){
        Object var1 = data.get("number");
        Object var2 = data.get("data");
        if (var1 == null || var2 == null) {
            return ResponseBean.ERRORDATA("传入的数据格式有误",data);
        }
        String number = (String) var1;
        List<Integer> list = (List) var2;
        for (Integer address :
                list) {
            tagService.displayNumber(address.byteValue(), number);
        }
        return ResponseBean.OK("批量关闭成功",data);
    }



    /**
     * 设置标签闪烁频率
     * @Param address
	 * @Param status
     * @Return com.hengxing.demo.model.ResponseBean
     * @Author hengxing
     * @Date 6/1/2023 11:41:11
     */
    @GetMapping("/blink/{address}/{status}")
    @Operation(
            summary = "设置标签闪烁频率",
            parameters = {
                    @Parameter(name = "address",description = "标签地址",example = "252"),
                    @Parameter(name = "status",description = "闪烁频率\n0,\"灭\"。1,\"常亮\"。2,\"2秒\"。3,\"1秒\"。4,\"0.5秒\"。5,\"0.25秒\"",example = "1")
            },
            responses = {
                    @ApiResponse(
                            description = "还没有建立连接，请先建立连接",
                            responseCode = "500",
                            content = @Content(mediaType = "application/json")
                    ),
                    @ApiResponse(
                            description = "地址应在1-200之内，252为全部标签",
                            responseCode = "501",
                            content = @Content(mediaType = "application/json")
                    ),
                    @ApiResponse(
                            description = "状态应该为0-5之间的整数",
                            responseCode = "502",
                            content = @Content(mediaType = "application/json")
                    ),
                    @ApiResponse(
                            description = "返回成功信息",
                            responseCode = "200",
                            content = @Content(mediaType = "application/json")
                    )
            }
    )
    public ResponseBean setBlinkStatus(@PathVariable int address,@PathVariable()int status){
        HashMap<Integer, String> helperMessage = new HashMap<>();
        helperMessage.put(0,"灭");
        helperMessage.put(1,"常亮");
        helperMessage.put(2,"2秒");
        helperMessage.put(3,"1秒");
        helperMessage.put(4,"0.5秒");
        helperMessage.put(5,"0.25秒");

        if (!tagService.isConnected())
            return ResponseBean.ERRORADDRESS("Not connected yet.Connect first!",helperMessage);
        if (address > 252) {
            HashMap<String, Object> data = new HashMap<>();
            data.put("error message","address should be 1 to 200.252 for all tags.");
            data.put("helper message",helperMessage);
            return ResponseBean.ERRORDATA("address is not allowed bigger than 252.",data);
        }
        if (status > 5 || status < 0){
            HashMap<String, Object> data = new HashMap<>();
            data.put("error message","Blink status should be between 0-5.");
            data.put("helper meaage",helperMessage);
            return ResponseBean.ERROR("status error",data);
        }
        tagService.AB_LED_Status((byte) address, (byte) status);
        return ResponseBean.OK("Set blink successful.");
    }

    /**
     * 批量设置标签闪烁频率
     * @Param data
     * @Return com.hengxing.demo.model.ResponseBean
     * @Author hengxing
     * @Date 6/2/2023 16:06:52
     */
    @PostMapping("/blink")
    @Operation(
            summary = "批量设置标签闪烁频率",
            description = "把地址列表的标签设置均为相同的闪烁频率",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "请求体中包装闪烁频率和地址列表，请求格式为map格式。其中频率为0-5的整数，地址是0-252之间的整数",
                    content = @Content(
                            mediaType = "application/json",
                            examples = {
                                    @ExampleObject(
                                            name = "成功示例",
                                            description = "设置地址为1，2，3的标签常亮",
                                            value = "{\n" +
                                                    "    \"status\": 1,\n" +
                                                    "    \"data\": [1,2,3]\n" +
                                                    "}"
                                    ),
                                    @ExampleObject(
                                            name = "失败示例",
                                            description = "data中的数据不为Integer类型",
                                            value = "{\n" +
                                                    "    \"status\": 1,\n" +
                                                    "    \"data\": [1,2,3.2]\n" +
                                                    "}"
                                    )
                            }
                    )
            )
    )
    public ResponseBean setBlinkStatusMulti(@RequestBody Map<String,Object> data){
        Object var1 = data.get("status");
        Object var2 = data.get("data");
        if (var1 == null || var2 == null) {
            return ResponseBean.ERRORDATA("传入的数据格式有误",data);
        }
        if (!(var1 instanceof Integer)){
            return ResponseBean.ERRORDATA("传入的数据格式有误，status应为Integer",data);
        }
        Integer status = (Integer) var1;
        if (status > 5 || status < 0){
            return ResponseBean.ERRORDATA("status应为0-5的整数",data);
        }
        if (!(var2 instanceof List<?>)){
            return ResponseBean.ERRORDATA("传入的数据格式有误，data应为一个list",data);
        }

        List<Integer> list = (List<Integer>) var2;
        for (Object address :
                list) {
            if (!(address instanceof Integer)){
                return ResponseBean.ERRORDATA("传入的数据格式有误，list中的元素应为Integer",data);
            }
            Integer integer = (Integer) address;
            System.out.println("integer = " + integer);
//            tagService.AB_LED_Status(address.byteValue(),status.byteValue());
        }
        return ResponseBean.OK("批量设置标签闪烁频率成功",data);
    }

    /**
     * 设置标签灯光颜色
     * @Param address
	 * @Param color
     * @Return com.hengxing.demo.model.ResponseBean
     * @Author hengxing
     * @Date 6/2/2023 09:56:41
     */
    @GetMapping("/color/{address}/{color}")
    @Operation(
            summary = "设置标签灯光颜色",
            description = "设置警示灯时，请继续设置灯光的闪烁频率，否则可能无效果",
            parameters = {
                    @Parameter(name = "address",description = "标签地址",example = "252"),
                    @Parameter(name = "color",description = "标签灯光颜色。0红1绿2黄3蓝4紫5浅蓝",example = "1")
            },
            responses = {
                    @ApiResponse(
                            description = "还没有建立连接，请先建立连接",
                            responseCode = "500",
                            content = @Content(mediaType = "application/json")
                    ),
                    @ApiResponse(
                            description = "地址应在1-200之内，252为全部标签",
                            responseCode = "501",
                            content = @Content(mediaType = "application/json")
                    ),
                    @ApiResponse(
                            description = "颜色应该为0-5之间的整数",
                            responseCode = "502",
                            content = @Content(mediaType = "application/json")
                    ),
                    @ApiResponse(
                            description = "返回成功信息",
                            responseCode = "200",
                            content = @Content(mediaType = "application/json")
                    )
            }
    )
    public ResponseBean setTagColor(@PathVariable int address,@PathVariable int color){
        HashMap<Object, String> helperMessage = new HashMap<>();
        helperMessage.put(0,"红");
        helperMessage.put(1,"绿");
        helperMessage.put(2,"黄");
        helperMessage.put(3,"蓝");
        helperMessage.put(4,"紫");
        helperMessage.put(5,"浅蓝");
        if (!tagService.isConnected())
            return ResponseBean.ERROR("Not connected yet.Connect first!",helperMessage);
        if (address > 252) {
            HashMap<String, Object> data = new HashMap<>();
            data.put("error message","address should be 1 to 200.252 for all tags.");
            data.put("helper message",helperMessage);
            return ResponseBean.ERRORADDRESS("address is not allowed bigger than 252.",data);
        }
        if (color > 5 || color < 0){
            HashMap<String, Object> data = new HashMap<>();
            data.put("error message","Tag color should be between 0-5.");
            data.put("helper meaage",helperMessage);
            return ResponseBean.ERRORDATA("status error",data);
        }
        tagService.AB_LED_color((byte) address, (byte) color);
        return ResponseBean.OK("Set color of tag successful.");
    }
}
